package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"strings"
)

func test1() {
	const jsonStream = `
	{"Name": "Ed", "Text": "Knock knock."}
	{"Name": "Sam", "Text": "Who's there?"}
	{"Name": "Ed", "Text": "Go fmt."}
	{"Name": "Sam", "Text": "Go fmt who?"}
	{"Name": "Ed", "Text": "Go fmt yourself!"}
`
	type Message struct {
		Name, Text string
	}
	dec := json.NewDecoder(strings.NewReader(jsonStream))
	for {
		var m Message
		if err := dec.Decode(&m); err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s: %s\n", m.Name, m.Text)
	}
}

type Animal int

const (
	Unknown Animal = iota
	Gopher
	Zebra
)

func (a *Animal) UnmarshalJSON(b []byte) error {
	var s string
	if err := json.Unmarshal(b, &s); err != nil {
		return err
	}
	switch strings.ToLower(s) {
	default:
		*a = Unknown
	case "gopher":
		*a = Gopher
	case "zebra":
		*a = Zebra
	}

	return nil
}

func (a Animal) MarshalJSON() ([]byte, error) {
	var s string
	switch a {
	default:
		s = "unknown"
	case Gopher:
		s = "gopher"
	case Zebra:
		s = "zebra"
	}

	return json.Marshal(s)
}

func test2() {
	blob := `["gopher","armadillo","zebra","unknown","gopher","bee","gopher","zebra"]`
	var zoo []Animal
	if err := json.Unmarshal([]byte(blob), &zoo); err != nil {
		log.Fatal(err)
	}
	census := make(map[Animal]int)
	for _, animal := range zoo {
		census[animal] += 1
	}
	fmt.Printf("Zoo Census:\n* Gophers: %d\n* Zebras:  %d\n* Unknown: %d\n",
		census[Gopher], census[Zebra], census[Unknown])
}

type Server struct {
	ServerName string
	ServerIP   string
}

type Serverslice struct {
	Servers []Server
}

func test3() {
	var server_list Serverslice
	str := `
	{
		"servers": [
			{
				"serverName": "Guangzhou_Base",
				"serverIP": "127.0.0.1",
				"test": 123
			},
			{
				"serverName": "Guangzhou_Base",
				"test": 123
			},
			{
				"serverIP": "127.0.0.1",
				"test": 123
			},
			{
				"serverName": "Beijing_Base",
				"serverIP": "127.0.0.2"
			}
		]
	}
	`
	err := json.Unmarshal([]byte(str), &server_list)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(str)
	fmt.Println(server_list)
	for i, s := range server_list.Servers {
		fmt.Println(i, s)
	}
}

func main() {
	test4()
}
